﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Input;
using System.Drawing;
using OpenTK.Graphics;
using Common;

namespace T03.ColoredCube {
    class MyGameWindow : GameWindow {
        public MyGameWindow() {
            this.Load += MyGameWindow_Load;
            this.Resize += MyGameWindow_Resize;
            this.RenderFrame += MyGameWindow_RenderFrame;
            this.Unload += MyGameWindow_Unload;
            this.Width = 1024;
            this.Height = 768;

        }


        private void MyGameWindow_RenderFrame(object sender, FrameEventArgs e) {
            GL.ClearColor(.1f, .1f, .99f, .9f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            Render();

            SwapBuffers();
            ProcessEvents();
        }
        Vao vao;
        Vbo vertexBuffer, colorBuffer;
        Shader shader;
        Matrix4 projection, view, model, mvp;
        VertexAttribManager attribs = new VertexAttribManager();
        //VboAttribsInfo vertexVboInfo, colorVboInfo;
        float[] vertexBufferData = {
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f, 1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
         1.0f,-1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f,-1.0f,
         1.0f,-1.0f,-1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f,-1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
         1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
         1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
         1.0f,-1.0f, 1.0f
    };
        float[] colorBufferData = {
        0.583f,  0.771f,  0.014f,
        0.609f,  0.115f,  0.436f,
        0.327f,  0.483f,  0.844f,
        0.822f,  0.569f,  0.201f,
        0.435f,  0.602f,  0.223f,
        0.310f,  0.747f,  0.185f,
        0.597f,  0.770f,  0.761f,
        0.559f,  0.436f,  0.730f,
        0.359f,  0.583f,  0.152f,
        0.483f,  0.596f,  0.789f,
        0.559f,  0.861f,  0.639f,
        0.195f,  0.548f,  0.859f,
        0.014f,  0.184f,  0.576f,
        0.771f,  0.328f,  0.970f,
        0.406f,  0.615f,  0.116f,
        0.676f,  0.977f,  0.133f,
        0.971f,  0.572f,  0.833f,
        0.140f,  0.616f,  0.489f,
        0.997f,  0.513f,  0.064f,
        0.945f,  0.719f,  0.592f,
        0.543f,  0.021f,  0.978f,
        0.279f,  0.317f,  0.505f,
        0.167f,  0.620f,  0.077f,
        0.347f,  0.857f,  0.137f,
        0.055f,  0.953f,  0.042f,
        0.714f,  0.505f,  0.345f,
        0.783f,  0.290f,  0.734f,
        0.722f,  0.645f,  0.174f,
        0.302f,  0.455f,  0.848f,
        0.225f,  0.587f,  0.040f,
        0.517f,  0.713f,  0.338f,
        0.053f,  0.959f,  0.120f,
        0.393f,  0.621f,  0.362f,
        0.673f,  0.211f,  0.457f,
        0.820f,  0.883f,  0.371f,
        0.982f,  0.099f,  0.879f
    };
        private void MyGameWindow_Load(object sender, EventArgs e) {

            VSync = VSyncMode.Off;
            GL.Enable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Less);
            vao = new Vao();
            shader = new Shader("shader.vs", "shader.fs");
            projection = Matrix4.CreatePerspectiveFieldOfView(GLUtility.ToRadians(45f), 4.0f / 3.0f, 0.1f, 100f);
            view = Matrix4.LookAt(new Vector3(4, 3, -3),
                new Vector3(0, 0, 0),
                new Vector3(0, 1, 0));
            model = Matrix4.Identity;
            mvp = model * view * projection;
            vertexBuffer = new Vbo(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, vertexBufferData);
            colorBuffer = new Vbo(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, colorBufferData);
            //vertexVboInfo = new VboAttribsInfo(vertexBuffer);
            //colorVboInfo = new VboAttribsInfo(colorBuffer);
            attribs.AddAttrib(3,vertexBuffer, VertexAttribPointerType.Float, false);
            attribs.AddAttrib(3, colorBuffer,VertexAttribPointerType.Float, false);
        }

        private void Render() {
            shader.Use();
            shader.SetMatrix4("MVP", ref mvp);
            //GL.EnableVertexAttribArray(0);
            //GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer.Id);
            //GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 12, 0);

            //GL.EnableVertexAttribArray(1);
            //GL.BindBuffer(BufferTarget.ArrayBuffer, colorBuffer.Id);
            //GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 12, 0);
            attribs.Enable();
            GL.DrawArrays(PrimitiveType.Triangles, 0, 12 * 3);
            GL.DisableVertexAttribArray(0);
            GL.DisableVertexAttribArray(1);
        }

        private void MyGameWindow_Resize(object sender, EventArgs e) {
            //int size = Math.Min(this.Width, this.Height);
            //GL.Viewport(0, 0, size,size);
            GL.Viewport(0, 0, Width, Height);
        }



        private void MyGameWindow_Unload(object sender, EventArgs e) {
            shader.Dispose();
            vao.Dispose();
            vertexBuffer.Dispose();
            colorBuffer.Dispose();
        }

    }
}
